home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / cgazv5n5.arc / XMSUMB.C < prev   
C/C++ Source or Header  |  1991-09-23  |  6KB  |  206 lines

  1. /*--- XMSUMB.C --------------------------- Listing 3 ------
  2.  * XMS UMB Functions. main() displays UMB's in use.
  3.  * Must be linked to xmsgen (Listing 1)
  4.  *
  5.  * by David Babcock
  6.  *
  7.  * Validated for Microsoft and Borland C/C++
  8.  *
  9.  * (c) 1991 C Gazette. Object Code may be used freely,
  10.  * source code may be used if authorship and publication
  11.  * are acknowledged.
  12.  *-------------------------------------------------------*/
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <dos.h>
  17.  
  18. #include "xms.h"
  19.  
  20. struct UMB
  21. {
  22.     unsigned int  segment ;
  23.     unsigned int  paragraphs ;
  24. } ;
  25.  
  26. /* This structure must be packed: don't let the compiler pad it.
  27.  * For MSC, this means that  #pragma pack(1)  is needed */
  28. #if !defined(__TURBOC__)
  29. #pragma pack(1) /* no packing */
  30. #endif
  31. struct MCB
  32. {
  33.     unsigned char signature ;
  34.     unsigned int owner ;
  35.     unsigned int size ;
  36. } ;
  37. #if !defined(__TURBOC__)
  38. #pragma pack() /* default packing */
  39. #endif
  40.  
  41. static struct UMB umb [ 16 ] ;
  42. static int umbs = 0 ;
  43.  
  44. #if 0
  45. /* This code is never to be used, but is left behind
  46.  * as a reminder not to implement something else like
  47.  * it. See text for details.
  48.  */
  49. void closeUMBs ( void )
  50. {
  51.     int i ;
  52.     for ( i = 0 ; i < umbs ; ++i )
  53.         ReleaseUpperMemoryBlock ( umb [ i ].segment ) ;
  54. }
  55. #endif
  56.  
  57. int comp ( const void *a, const void *b )
  58. {
  59.     register unsigned int au,bu ;
  60.  
  61.     au = ((struct UMB*)a)->segment ;
  62.     bu = ((struct UMB*)b)->segment ;
  63.  
  64.     return ( au < bu ? -1 : ( au > bu ) ) ;
  65. }
  66.  
  67. void main ( void )
  68. {
  69.     int i ;
  70.     unsigned paragraphs;
  71.     struct MCB far *mcbPtr ;
  72.     struct MCB far *mcbPtrZ ;
  73.     union REGS regs ;
  74.     struct SREGS sregs ;
  75.     unsigned int ver ;
  76.     int firstUMB ;
  77.  
  78.     ver = ( unsigned int ) GetXMSVersionNumber() ;
  79.     printf ( "XMS version %s\n", PrintXMSVersionNumber ( ver ));
  80.  
  81.     if ( ver >= 0x200 )
  82.     {
  83.         /* scarf up all available UMBs */
  84.  
  85.         #if 0 /* never used - see text */
  86.         atexit ( closeUMBs ) ;
  87.         #endif
  88.         for ( firstUMB = 1 ; ; firstUMB = 0 )
  89.         {
  90.             RequestUpperMemoryBlock ( 0xFFFF ) ;
  91.             if ( firstUMB )
  92.                 printf ( "Largest free upper memory block:\n" );
  93.             printf ( "%xh paragraphs\n", xms_struc.ret_dx );
  94.  
  95.             if ( xms_struc.ret_dx > 0 )
  96.             {
  97.                 RequestUpperMemoryBlock ( xms_struc.ret_dx ) ;
  98.                 umb [ umbs ].segment = xms_struc.ret_bx ;
  99.                 umb [ umbs++ ].paragraphs = xms_struc.ret_dx ;
  100.             }
  101.             else break ;
  102.         }
  103.  
  104.         /* sort the UMBs by address */
  105.  
  106.         qsort ( umb, umbs, sizeof ( umb[0] ), comp ) ;
  107.  
  108.         /* insert the UMBs in the DOS allocation chain */
  109.         /* get the base of the chain */
  110.  
  111.         regs.h.ah = 0x52 ;
  112.         intdosx ( ®s, ®s, &sregs ) ;
  113.         mcbPtr = MK_FP ( sregs.es, regs.x.bx - 2 ) ;
  114.  
  115.         /* get the last link: its signature is 'Z' */
  116.  
  117.         mcbPtr = MK_FP ( *((unsigned far*)mcbPtr), 0 ) ;
  118.         for ( ;; )
  119.         {
  120.             if ( mcbPtr->signature == 'Z' )
  121.             {
  122.                 mcbPtrZ = mcbPtr ;
  123.                 break ;
  124.             }
  125.             mcbPtr = MK_FP ( FP_SEG(mcbPtr) +
  126.                              mcbPtr->size + 1, 0 ) ;
  127.         }
  128.  
  129.         printf ( "\n\nUMBs:\nsegment\t\tparagraphs\n\n" ) ;
  130.         paragraphs = 0;
  131.  
  132.         for ( i = 0 ; i < umbs ; ++i )
  133.         {
  134.             printf ( "%04x\t\t%04xh\n",
  135.                 umb [ i ].segment, umb [ i ].paragraphs ) ;
  136.             paragraphs += umb [ i ].paragraphs;
  137.         }
  138.  
  139.         if ( umbs > 0 )
  140.         {
  141.             printf("\n\nCan add to allocation chain."
  142.                    " Will add a total of %u bytes.",
  143.                    paragraphs * 16);
  144.  
  145.          /* In each memory block, set aside the first and
  146.             last paragraphs for MCBs. Make DOS the owner of the
  147.             first, and a dummy process the owner of the last. */
  148.  
  149.             for ( i = 0 ; i < umbs - 1 ; ++i )
  150.             {
  151.                 mcbPtr = MK_FP ( umb [ i ].segment, 0 ) ;
  152.                 mcbPtr->signature = 'M' ;
  153.                 mcbPtr->owner = 0 ;
  154.                 mcbPtr->size = umb [ i ].paragraphs - 2 ;
  155.  
  156.                 mcbPtr = MK_FP ( umb [ i ].segment
  157.                             + umb [ i ].paragraphs - 1, 0 ) ;
  158.                 mcbPtr->signature = 'M' ;
  159.                 mcbPtr->owner = 0xFFFF ;
  160.                 mcbPtr->size = umb [ i + 1 ].segment
  161.                             - FP_SEG ( mcbPtr ) - 1 ;
  162.             }
  163.             mcbPtr = MK_FP ( umb [ i ].segment, 0 ) ;
  164.             mcbPtr->signature = 'Z' ;
  165.             mcbPtr->owner = 0 ;
  166.             mcbPtr->size = umb [ i ].paragraphs - 1 ;
  167.  
  168.             /* modify the last DOS block to add the
  169.                new blocks to the chain */
  170.  
  171.             mcbPtrZ->signature = 'M' ;
  172.             mcbPtr = MK_FP ( FP_SEG(mcbPtrZ) +
  173.                             mcbPtrZ->size--, 0 ) ;
  174.             mcbPtr->signature = 'M' ;
  175.             mcbPtr->owner = 0xFFFF ;
  176.             mcbPtr->size = umb [ 0 ].segment -
  177.                             FP_SEG ( mcbPtr ) - 1 ;
  178.  
  179.             regs.h.ah = 0x52 ;
  180.             intdosx ( ®s, ®s, &sregs ) ;
  181.             mcbPtr = MK_FP ( sregs.es, regs.x.bx - 2 ) ;
  182.  
  183.             /* get the last link: its signature is 'Z' */
  184.  
  185.             mcbPtr = MK_FP ( *((unsigned far*)mcbPtr), 0 ) ;
  186.  
  187.             /* display the allocation chain */
  188.  
  189.             printf ( "\n\n\nAllocation chain links:\n" ) ;
  190.             printf ( "M/Z\t\tsegment\t\towner\t\tsize\n\n" ) ;
  191.             for ( ;; )
  192.             {
  193.                 printf ( "%c\t\t%04x\t\t%04x\t\t%4xh\n",
  194.                     mcbPtr->signature, FP_SEG(mcbPtr),
  195.                             mcbPtr->owner, mcbPtr->size ) ;
  196.                 if ( mcbPtr->signature == 'Z' )
  197.                 {
  198.                     mcbPtrZ = mcbPtr ;
  199.                     break ;
  200.                 }
  201.                 mcbPtr = MK_FP ( FP_SEG(mcbPtr) +
  202.                                  mcbPtr->size + 1, 0 ) ;
  203.             }
  204.         }
  205.     }
  206. }